#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include <GLUT/glut.h>
#include "GB.h"

#define WIDTH 160
#define HEIGHT 144
#define GLUT_KEY_ESCAPE 27
#define GB_KEY_A 'a'
#define GB_KEY_B 'z'
#define GB_KEY_START 13
#define GB_KEY_SELECT 39
#define GB_RESTART 'r'
#define GB_TOGGLE_PAUSE ' '

GBDevice * device = 0;

void quit()
{
	GBDeviceDestroy(device);
}

void init(int argc, char * argv[])
{
	atexit(quit);

	//TODO: setup functions for gb!
	//GBSetBitmapCreateFunc(create_bitmap);
	//GBSetBitmapDestroyFunc(destroy_bitmap);

	device = GBDeviceCreate();
	if (!device)
		exit(0);

	// TODO: load rom!
	// TODO: sound

	glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
}

void draw()
{
	glClear(GL_COLOR_BUFFER_BIT);

	// TODO:

	glutSwapBuffers();
}

void idle()
{
	glutPostRedisplay();
}

void special_key_pressed(int key, int mouse_x, int mouse_y)
{
	switch (key)
	{
	case GLUT_KEY_UP:
		printf("+U");
		break;

	case GLUT_KEY_DOWN:
		printf("+D");
		break;

	case GLUT_KEY_LEFT:
		printf("+L");
		break;

	case GLUT_KEY_RIGHT:
		printf("+R");
		break;
	}
}

void special_key_released(int key, int mouse_x, int mouse_y)
{
	switch (key)
	{
	case GLUT_KEY_UP:
		printf("-U");
		break;

	case GLUT_KEY_DOWN:
		printf("-D");
		break;

	case GLUT_KEY_LEFT:
		printf("-L");
		break;

	case GLUT_KEY_RIGHT:
		printf("-R");
		break;
	}
}

void key_pressed(unsigned char key, int mouse_x, int mouse_y)
{
	switch (key)
	{
	case GLUT_KEY_ESCAPE:
		exit(0);

	case GB_KEY_A:
		printf("+A");
		break;

	case GB_KEY_B:
		printf("+B");
		break;

	case GB_KEY_START:
		printf("+START");
		break;

	case GB_KEY_SELECT:
		printf("+SELECT");
		break;
	}
}

void key_released(unsigned char key, int mouse_x, int mouse_y)
{
	switch (key)
	{
	case GB_KEY_A:
		printf("-A");
		break;

	case GB_KEY_B:
		printf("-B");
		break;

	case GB_KEY_START:
		printf("-START");
		break;

	case GB_KEY_SELECT:
		printf("-SELECT");
		break;
	}
}

void window_resized(int width, int height)
{
	glutReshapeWindow(WIDTH, HEIGHT);
}

void window_visible_change(int state)
{
	if (state == GLUT_VISIBLE)
		glutIdleFunc(idle);
	else
		glutIdleFunc(0);
}

int main(int argc, char* argv[])
{
	glutInit(&argc, argv);
	glutInitWindowSize(WIDTH, HEIGHT);
	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
	glutCreateWindow("iGBC");
	glutDisplayFunc(draw);
	glutReshapeFunc(window_resized);
	glutKeyboardFunc(key_pressed);
	glutKeyboardUpFunc(key_released);
	glutSpecialFunc(special_key_pressed);
	glutSpecialUpFunc(special_key_released);
	glutVisibilityFunc(window_visible_change);
	glutIgnoreKeyRepeat(1);
	init(argc, argv);
	glutMainLoop();
	return 0;
}
